package com.fu.shop.service.Impl;

import com.fu.core.common.BusinessException;
import com.fu.core.common.ExceptionCode;
import com.fu.core.pojo.*;
import com.fu.core.service.impl.BaseServiceImpl;
import com.fu.shop.mapper.GoodsMapper;
import com.fu.shop.mapper.PictureMapper;
import com.fu.shop.mapper.SkuMapper;
import com.fu.shop.mapper.TypeMapper;
import com.fu.shop.repository.GoodsEsVoRepository;
import com.fu.shop.service.GoodsService;
import com.fu.shop.service.PictureService;
import com.fu.shop.service.SkuService;
import com.fu.shop.service.TypeService;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import tk.mybatis.mapper.entity.Example;

import java.sql.Timestamp;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author 付龙江
 * @date 2022/2/5 11:30
 */
@Service("goodsService")
@Transactional(rollbackFor = Throwable.class)
public class GoodsServiceImpl extends BaseServiceImpl<Goods> implements GoodsService {

    /**
     * 商品秒杀信息
     */
    private static  final String GOODS_SECKILL="goodsSeckill:";


    GoodsMapper goodsMapper;
    TypeService typeService;
    TypeMapper  typeMapper;
    SkuService skuService;
    RedisTemplate<String,Object> redisTemplate;
    ValueOperations<String,Object> stringOps;
    GoodsEsVoRepository goodsEsVoRepository;
    PictureMapper pictureMapper;
    PictureService pictureService;
    SkuMapper skuMapper;

    @Autowired(required = false)
    public GoodsServiceImpl(GoodsMapper goodsMapper, TypeService typeService,TypeMapper  typeMapper,
                            SkuService skuService, RedisTemplate<String, Object> redisTemplate,
                            GoodsEsVoRepository goodsEsVoRepository,PictureMapper pictureMapper,
                            PictureService pictureService,SkuMapper skuMapper) {
        this.goodsMapper = goodsMapper;
        this.typeService = typeService;
        this.skuService = skuService;
        this.typeMapper = typeMapper;
        this.redisTemplate = redisTemplate;
        this.stringOps = redisTemplate.opsForValue();
        this.goodsEsVoRepository = goodsEsVoRepository;
        this.pictureMapper = pictureMapper;
        this.pictureService = pictureService;
        this.skuMapper = skuMapper;
    }

    /**
     * 查询商品类型集合
     * @param typeName 类型名称
     * @param page     页码
     * @param size     长度
     * @return 返回类型集合
     */
    @Override
    public PageInfo<Type> selectTypeList(String typeName, Integer page, Integer size) {
        PageHelper.startPage(page,size);
        List<Type> typeList = null;
        if (StringUtils.isEmpty(typeName)){
            //没有传类型名称时  就是全查询
             typeList = typeService.selectAll();
        }else {
            //传了类型名称 模糊查询
            Example example = new Example(Type.class);
            Example.Criteria criteria = example.createCriteria();
            criteria.andLike("typeName","%"+typeName+"%");
            typeList = typeMapper.selectByExample(example);
        }
        return PageInfo.of(typeList);
    }

    /**
     * 修改类型的状态
     *
     * @param typeId     类型编号
     * @param typeStatus 要修改成的状态（1是开启 0是关闭）
     * @throws Exception 异常处理
     */
    @Override
    public void updateTypeStatus(Integer typeId, Integer typeStatus) throws Exception {
        //根据id 判断是否有该类型
        Type type = typeService.selectByPk(typeId);
        if (type == null){
            throw new BusinessException(ExceptionCode.PARAMETER_PASSING_EXCEPTION);
        }
        //有该类型就改状态
        type.setTypeStatus(typeStatus);
        typeService.save(type);
    }

    /**
     * @return 顶级分类的下拉列表
     */
    @Override
    public List<Type> topTypeList() {
        Example example = new Example(Type.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("typeParentId",0);
        return typeMapper.selectByExample(example);
    }

    @Override
    public void updateOrAddType(Type type) throws Exception {
        if (type == null){
            throw new BusinessException(ExceptionCode.PARAMETER_PASSING_EXCEPTION);
        }
        typeService.save(type);
    }

    /**
     * @param goodsName 商品名称
     * @param page      页码
     * @param size      每页尺寸
     * @return 返回对应数据
     */
    @Override
    public PageInfo<Map<String, Object>> selectGoodsList(String goodsName, Integer page, Integer size) {
        PageHelper.startPage(page,size);
        List<Map<String, Object>> list = goodsMapper.selectGoodsList(goodsName);
        return PageInfo.of(list);
    }

    @Override
    public List<Map<String, Object>> uploadGoodsList() {
        return goodsMapper.selectGoodsList(null);
    }

    /**
     * 商品上下架
     *
     * @param goodsId     商品编号
     * @param goodsStatus 看是上架还是下架状态  1上架  0是下架状态
     * @throws Exception 异常处理
     */
    @Override
    public void updateGoodsStatus(Integer goodsId, Integer goodsStatus) throws Exception {
        //根据商品编号去拿到商品对象
        Goods goods = selectByPk(goodsId);
        if (goods == null){
            throw new BusinessException(ExceptionCode.PARAMETER_PASSING_EXCEPTION);
        }
        goods.setGoodsStatus(goodsStatus);
        //判断商品是否是第一次上架
        if (goods.getGoodsStartShelf() == null){
            goods.setGoodsStartShelf(new Timestamp(System.currentTimeMillis()));
        }
        //修改数据库中商品的状态
        save(goods);
        if (goodsStatus == 1){
            //上架商品 从数据库中拿到商品的简略信息
            GoodsEsVo goodsEsVo = goodsMapper.selectGoodsEsVoById(goodsId);
            //更新到es中
            goodsEsVoRepository.save(goodsEsVo);
            //判断商品信息中是否开启秒杀
            if (goods.getGoodsSeckill() == 1){
                //开启了秒杀，将商品详情存入到redis中
                GoodsDetailsVo goodsDetailsVo = new GoodsDetailsVo();
                //商品信息
                goodsDetailsVo.setGoods(goods);
                //sku信息
                Example skuExample = new Example(Sku.class);
                Example.Criteria skuCriteria = skuExample.createCriteria();
                skuCriteria.andEqualTo("goodsId",goods.getGoodsId());
                List<Sku> skus = skuMapper.selectByExample(skuExample);
                goodsDetailsVo.setSkus(skus);
                //图片信息
                Example pictureExample = new Example(Picture.class);
                Example.Criteria pictureCriteria = pictureExample.createCriteria();
                pictureCriteria.andEqualTo("goodsId",goods.getGoodsId());
                List<Picture> pictures = pictureMapper.selectByExample(pictureExample);
                goodsDetailsVo.setPictures(pictures);
                //存入redis
                stringOps.set(GOODS_SECKILL+goods.getGoodsId(),goodsDetailsVo);
            }


        }else if (goodsStatus == 0){
            //下架商品 把es中的商品信息删除
            goodsEsVoRepository.deleteGoodsEsVoById(goodsId);
            //把redis中对应的key删掉
            if (redisTemplate.hasKey(GOODS_SECKILL+goods.getGoodsId())){
                redisTemplate.delete(GOODS_SECKILL+goods.getGoodsId());
            }
        }else {
            //传参有误
            throw new BusinessException(ExceptionCode.PARAMETER_PASSING_EXCEPTION);
        }
    }

    /**
     * @return 商品选择的二级类型
     */
    @Override
    public List<Type> goodsDetailTypeList() {
        Example example = new Example(Type.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("typeStatus",1).andNotEqualTo("typeParentId",0);
        return typeMapper.selectByExample(example);
    }

    /**
     * @param goodsId 商品编号
     * @return 所有商品详情信息
     * @throws Exception 异常处理
     */
    @Override
    public Map<String, Object> selectGoodsDetails(Integer goodsId) throws Exception {
        Map<String,Object> map = new HashMap<>(16);
        Map<String, Object> goods = goodsMapper.selectGoodsDetails(goodsId);
        if (goods == null){
            throw new BusinessException(ExceptionCode.PARAMETER_PASSING_EXCEPTION);
        }
        map.put("goods",goods);
        Example example = new Example(Picture.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("goodsId",goodsId);
        List<Picture> pictures = pictureMapper.selectByExample(example);
        map.put("pictures",pictures);
        Example example1 = new Example(Sku.class);
        Example.Criteria criteria1 = example1.createCriteria();
        criteria1.andEqualTo("goodsId",goodsId);
        List<Sku> skus = skuMapper.selectByExample(example1);
        map.put("skus",skus);
        return map;
    }

    /**
     * 添加商品
     *
     * @param goods    商品
     * @param skus     sku信息
     * @param pictures 商品特色图
     * @throws Exception 异常处理
     */
    @Override
    public void addGoods(Goods goods, List<Sku> skus, List<Picture> pictures) throws Exception {
        //先添加商品信息
        goods.setGoodsStatus(0);
        goods.setGoodsSeckill(0);
        Goods newGoods = insertTSelective(goods);
        //添加商品后拿到商品id  再去添加商品的sku
        for (Sku sku : skus) {
            sku.setGoodsId(newGoods.getGoodsId());
            skuService.save(sku);
        }
        //添加商品picture
        for (Picture picture : pictures) {
            picture.setGoodsId(newGoods.getGoodsId());
            pictureService.save(picture);
        }

    }

    /**
     * 添加商品
     *
     * @param goods    商品
     * @param skus     sku信息
     * @param pictures 商品特色图
     * @throws Exception 异常处理
     */
    @Override
    public void updateGoods(Goods goods, List<Sku> skus, List<Picture> pictures) throws Exception {
        //编辑商品后，商品状态会自动改成下架
        goods.setGoodsStatus(0);
        updateGoodsStatus(goods.getGoodsId(),0);
        //在将新商品信息存入数据库
        save(goods);
        //存sku信息 先拿到原来的sku信息
        Example skuExample = new Example(Sku.class);
        Example.Criteria skuCriteria = skuExample.createCriteria();
        skuCriteria.andEqualTo("goodsId",goods.getGoodsId());
        //删除原来所有的sku信息
        skuMapper.deleteByExample(skuExample);
        //插入现在的sku信息
        for (Sku sku : skus) {
            skuService.insertTSelective(sku);
        }

        //删除原来的图片信息
        Example pictureExample = new Example(Picture.class);
        Example.Criteria pictureCriteria = pictureExample.createCriteria();
        pictureCriteria.andEqualTo("goodsId",goods.getGoodsId());
        pictureMapper.deleteByExample(pictureExample);
        //插入现在的Picture信息
        for (Picture picture : pictures) {
            pictureService.insertTSelective(picture);
        }
    }
}
